package com.luoxue.execsql.rest.bean.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.luoxue.execsql.rest.entity.SysDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 扩展 Spring 的 AbstractRoutingDataSource 抽象类，重写 determineCurrentLookupKey 方法
 * 动态数据源
 * determineCurrentLookupKey() 方法决定使用哪个数据源
 *
 * @author xiaohe
 * @version V1.0.0
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    Map<Object, Object> targetDataSources = new HashMap<>();

    /**
     * 决定使用哪个数据源之前需要把多个数据源的信息以及默认数据源信息配置好
     *
     * @param defaultTargetDataSource 默认数据源
     */
    public DynamicDataSource(DataSource defaultTargetDataSource) {
        this.setDefaultTargetDataSource(defaultTargetDataSource);
        this.setTargetDataSources(new HashMap<>());
    }

    public void setTargetDataSources() {
        this.setTargetDataSources(targetDataSources);
        this.afterPropertiesSet();
    }

    public void updateTargetDataSources(List<SysDataSource> sysDataSourceList) {
        sysDataSourceList.forEach(sysDataSource -> {
            DruidDataSource druidDataSource = DynamicThreadLocalHolder.createDruidDataSource(sysDataSource);
            targetDataSources.put(this.resolveSpecifiedLookupKey(sysDataSource.getDataSourceName()), this.resolveSpecifiedDataSource(druidDataSource));
        });
        setTargetDataSources();
    }

    public void updateTargetDataSource(SysDataSource sysDataSource) {
        DruidDataSource druidDataSource = DynamicThreadLocalHolder.createDruidDataSource(sysDataSource);
        targetDataSources.put(this.resolveSpecifiedLookupKey(sysDataSource.getDataSourceName()), this.resolveSpecifiedDataSource(druidDataSource));
        setTargetDataSources();
    }

    public void deleteTargetDataSource(SysDataSource sysDataSource) {
        targetDataSources.remove(this.resolveSpecifiedLookupKey(sysDataSource.getDataSourceName()));
        setTargetDataSources();
    }


    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicThreadLocalHolder.getDataSource();
    }


}
